#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
 
#define SOCKET_PATH "/tmp/mouse_click_socket"
#define BUFFER_SIZE 1024

int main() {
    char buf[4]; // 每次读取3个字节，对应于x, y, 和按钮状态
    int server_fd;
    struct sockaddr_un server_addr, client_addr;
    socklen_t client_addr_size;
    char buffer[BUFFER_SIZE];
    ssize_t bytes_read;
    int mouse_fd;
    
    struct timeval timeout;
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    
    // 创建socket
    server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (server_fd == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }
    
    // 设置socket地址结构
    server_addr.sun_family = AF_UNIX;
    strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);
    unlink(SOCKET_PATH); // 确保之前的socket文件被删除，避免绑定失败
    
    // 绑定socket到路径
    if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("bind");
        exit(EXIT_FAILURE);
    }
    
    // 监听连接请求
    if (listen(server_fd, 0) == -1) { // 第二个参数是等待队列的最大长度
        perror("listen");
        exit(EXIT_FAILURE);
    }
    chmod(SOCKET_PATH, 0777);

    mouse_fd = open("/dev/input/mice", O_RDONLY);
    if (mouse_fd < 0) {
        perror("Failed to open /dev/input/mice");
        exit(EXIT_FAILURE);
    }

    printf("Server started.\r\n");
    
    // 接受连接请求
    while(1) {
        fd_set readfds;
        int client_fd;
        int req=0;
        int seq=0;
        
        char mouse_info[50];
        
        int nfds;
        
        client_addr_size = sizeof(client_addr);
        client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_size);
        if (client_fd == -1) {
            perror("accept");
            break;
        }
        printf("connect\n");
        
        nfds = (mouse_fd>client_fd)?mouse_fd:client_fd;

        // 读取数据并发送响应
        while(1){
            int ret;
            
            FD_ZERO(&readfds);
            FD_SET(client_fd, &readfds);
            FD_SET(mouse_fd, &readfds);
            timeout.tv_sec = 5;
            timeout.tv_usec = 0;
            ret = select(nfds+1,&readfds,NULL,NULL,&timeout);
            if ( ret<=0 ){
                perror("select");
                continue;
            }
            if(FD_ISSET(client_fd, &readfds)) {
                ret -= 1;
                bytes_read = read(client_fd, buffer, BUFFER_SIZE);
                if (bytes_read == -1) {
                    perror("read");
                    break;
                } 
                else if(bytes_read>3){
                    buffer[bytes_read]=0;
                    if( strncmp(buffer, "get", 3)==0 ) {
                        req += 1;
                        printf("req: %s", buffer);
                        // char *msg;
                        // msg = get_mouse_info( mouse_fd );
                        // write(client_fd, msg, strlen(msg));
                        // free(msg);
                    }
                    else if( strncmp(buffer, "bye", 3)==0 ){
                        req = 0;
                        printf("recv: bye\n");
                        break;
                    }
                    else if( strncmp(buffer, "quit", 4)==0 ){
                        printf("recv: quit\n");
                        goto END;
                    }
                    else {
                        write(client_fd, "bye\n",4);
                        break;
                    }
                    //write(client_fd, "Hello from server\n", 18); // 发送响应数据给客户端
                }
            }

            if( ret>0 && FD_ISSET(mouse_fd,&readfds)) {
                ret -= 1;
                buf[0] = 0;
                if (read(mouse_fd, buf, 3) == 3) {
                    int buttons = buf[0]&0x07; // 按钮状态（左，中，右）
                    //int dx = buf[1]; // 鼠标水平移动距离
                    //int dy = buf[2]; // 鼠标垂直移动距离
                    //int x,y;
                    
                    if(buttons > 0 && req>0) {
                        int sz;

                        sz = sprintf(mouse_info, "{\"id\":%d,\"button\":%d}\r\n", seq++, buttons);
                        mouse_info[sz]=0;

                        write(client_fd, mouse_info, strlen(mouse_info));
                        req -= 1;

                        printf("%s",mouse_info);
                    }
                    // 处理鼠标移动和点击事件
                    //printf("dx: %d, dy: %d, buttons: %d\n", dx, dy, buttons);
                }
            }
            
        }


        close(client_fd);
        
    }
    
    
    
    
    // 关闭socket连接和文件描述符
END:
    close(server_fd);
    unlink(SOCKET_PATH); // 删除socket文件，清理工作
    close(mouse_fd);
    return 0;
}
